﻿using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Text;
using ONG.Componentes.AccesoDatos.Model.TallerArtesanal;

namespace ONG.Componentes.AccesoDatos.Logic.Facade
{
    public static class OrdenPedido
    {

        /// <summary>
        /// Se obtiene la orden de pedido 
        /// </summary>
        /// <param name="numOrden">ID de la Orden de Pedido</param>
        /// <returns>Objeto</returns>
        public static TA_OrdenPedido ObtenerOrdenPedido(int? numOrden)
        {
            using (var data = new TallerArtesanalDataContext())
            {
                return data.TA_OrdenPedido.FirstOrDefault(op => op.IdOrdenPedido == numOrden);
            }
        }

        /// <summary>
        /// Se obtiene el listado de Ordenes de Pedido
        /// </summary>
        /// <returns></returns>
        public static List<TA_OrdenPedido> ListadoOrdenPedido(int? idSupervisor, DateTime? FechaEntregaInicio, DateTime? FechaEntregaFin, string CodOrdenPedido = null, string Asignado = null)
        {
            using (var data = new TallerArtesanalDataContext())
            {
                List<TA_OrdenPedido> lista;

                if (idSupervisor == null && string.IsNullOrWhiteSpace(CodOrdenPedido) && string.IsNullOrWhiteSpace(Asignado) && FechaEntregaInicio == null && FechaEntregaFin == null)
                {
                    lista = data.TA_OrdenPedido.ToList();
                    return lista;
                }

                if (FechaEntregaInicio == null && FechaEntregaFin == null)
                {
                    lista = data.TA_OrdenPedido.Where(x => x.IdSupervisor.Equals(idSupervisor) ||
                                                        x.CodOrdenPedido.ToLower().Contains(CodOrdenPedido)).ToList();
                }
                else
                {
                    lista = data.TA_OrdenPedido.Where(x => (x.FechaEntrega > (FechaEntregaInicio ?? SqlDateTime.MinValue.Value) && x.FechaEntrega < (FechaEntregaFin ?? SqlDateTime.MaxValue.Value))).ToList();
                }

                if (lista.Count > 0)
                {
                    foreach (var taOrdenPedido in lista)
                    {
                        taOrdenPedido.TA_DetalleOrdenPedido = taOrdenPedido.TA_DetalleOrdenPedido;

                        var estado = 0;
                        foreach (var detOrdenPedido in taOrdenPedido.TA_DetalleOrdenPedido)
                        {
                            detOrdenPedido.TA_ProgramacionTallers = detOrdenPedido.TA_ProgramacionTallers;
                            estado += detOrdenPedido.TA_ProgramacionTallers.Count;
                        }
                        taOrdenPedido.idEstado = estado > 0 ? 1 : 2;
                        taOrdenPedido.Estado = estado > 0 ? "Asignada" : "Sin Asignar";
                    }
                }

                if (!string.IsNullOrEmpty(Asignado) && Asignado != "-1")
                {
                    lista = lista.Where(e => e.idEstado == Convert.ToInt16(Asignado)).ToList();
                }

                return lista;
            }
        }

        /// <summary>
        /// Se obtiene el detalle de las Ordenes de Pedido
        /// </summary>
        /// <param name="numOrden">numero de orden de pedido</param>
        /// <returns>Listado de Detalle de Ordenes de Pedido</returns>
        public static List<TA_DetalleOrdenPedido> ListadoDetalleOrdenPedido(int? numOrden)
        {
            using (var data = new TallerArtesanalDataContext())
            {
                List<TA_DetalleOrdenPedido> detallePedido;
                if (numOrden == null)
                {
                    detallePedido = data.TA_DetalleOrdenPedido.ToList();
                }
                else
                {
                    detallePedido = data.TA_DetalleOrdenPedido.Where(x => x.IdOrdenPedido == numOrden).ToList();
                }

                foreach (var taDetalleOrdenPedido in detallePedido)
                {
                    taDetalleOrdenPedido.TA_Producto = taDetalleOrdenPedido.TA_Producto;
                    taDetalleOrdenPedido.TA_Producto.TA_LineaProductiva = taDetalleOrdenPedido.TA_Producto.TA_LineaProductiva;
                    taDetalleOrdenPedido.TA_ProgramacionTallers = taDetalleOrdenPedido.TA_ProgramacionTallers;

                    foreach (var progTaller in taDetalleOrdenPedido.TA_ProgramacionTallers)
                    {
                        taDetalleOrdenPedido.cantidadAsignadaATalleres += progTaller.CantidadAsignadas ?? 0;
                    }

                    taDetalleOrdenPedido.cantidadAsignadaATalleres = (int)(taDetalleOrdenPedido.Cantidad -
                                                                            taDetalleOrdenPedido.cantidadAsignadaATalleres);

                }

                return detallePedido;

            }
        }

        /// <summary>
        /// Se obtiene el listado de products
        /// </summary>
        /// <returns>Listado del Tipo Producto</returns>
        public static List<TA_Producto> ListadoProducto()
        {
            using (var data = new TallerArtesanalDataContext())
            {
                return data.TA_Producto.ToList();
            }
        }
        /// <summary>
        /// Se obtiene el listado de compradores
        /// </summary>
        /// <returns>Listado del Tipo Comprador</returns>
        public static List<TA_Comprador> ListadoComprador()
        {
            using (var data = new TallerArtesanalDataContext())
            {
                return data.TA_Comprador.ToList();
            }
        }

        public static List<TA_Taller> ListadoTallerDisponible(DateTime? fechaInicio, DateTime? fechaFin)
        {

            List<TA_Taller> lista = null;

            using (var data = new TallerArtesanalDataContext())
            {
                if (!fechaInicio.HasValue && !fechaFin.HasValue)
                {
                    lista = data.TA_Taller.ToList();
                }
                else if (fechaInicio.HasValue && !fechaFin.HasValue)
                {
                    lista = data.TA_Taller.Where(t => t.FechaInicio == fechaInicio).ToList();
                }
                else if (!fechaInicio.HasValue && fechaFin.HasValue)
                {
                    lista = data.TA_Taller.Where(t => t.FechaFin == fechaFin).ToList();
                }
                else if (fechaInicio.HasValue && fechaFin.HasValue)
                {
                    lista = data.TA_Taller.Where(t => t.FechaInicio >= fechaInicio && t.FechaFin <= fechaFin).ToList();
                }

                if (lista.Count > 0)
                {
                    foreach (var taTaller in lista)
                    {
                        if (taTaller.FechaInicio != null)
                        {
                            DateTime d1 = (DateTime) taTaller.FechaInicio;
                            DateTime d2 = (DateTime) taTaller.FechaFin;

                            TimeSpan t1 = new TimeSpan(d1.Ticks);
                            TimeSpan t2 = new TimeSpan(d2.Ticks);

                            taTaller.CantidadDiasDisponible = (int) t2.Subtract(t1).TotalDays + 1;
                        }
                        
                        
                    }
                }

            }

            return lista;
        }

        /// <summary>
        /// Se obtiene todas las Programaciones de una Orden de Pedido
        /// </summary>
        /// <param name="numOrden">numero de orden de pedido</param>
        /// <returns>Listado de Programacion</returns>
        public static List<TA_ProgramacionTaller> ListadoProgramacion(int? numOrden)
        {

            List<TA_ProgramacionTaller> programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {

                programacionTaller = (from pro in data.TA_ProgramacionTallers
                                      join dOp in data.TA_DetalleOrdenPedido on pro.IdDetallePedido equals dOp.IdDetallePedido
                                      where dOp.IdOrdenPedido == numOrden
                                      select pro).ToList();

                foreach (var taProgramacion in programacionTaller)
                {
                    taProgramacion.TA_DetalleOrdenPedido = taProgramacion.TA_DetalleOrdenPedido;
                    taProgramacion.TA_DetalleOrdenPedido.TA_Producto = taProgramacion.TA_DetalleOrdenPedido.TA_Producto;
                }
                return programacionTaller;
            }
        }
        /// <summary>
        /// Se obtiene los Talleres asignados a un (Programacion-Detalle de Pedido)
        /// </summary>
        /// <param name="idProgramacion"></param>
        /// <returns></returns>
        public static List<TA_ProgramacionTaller> ListadoProgramacionTaller(int? idProgramacionTaller)
        {
            List<TA_ProgramacionTaller> programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {

                programacionTaller = (from proTall in data.TA_ProgramacionTallers
                                      where proTall.IdProgramacionTaller == idProgramacionTaller
                                      select proTall).ToList();

                foreach (var taProgramacion in programacionTaller)
                {
                    taProgramacion.TA_Taller = taProgramacion.TA_Taller;
                }

                return programacionTaller;

            }
        }

        public static List<TA_ProgramacionTaller> ListadoProgramacionTallerByIdDetallePedido(int idDetallePedido)
        {
            List<TA_ProgramacionTaller> programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {

                programacionTaller = (from proTall in data.TA_ProgramacionTallers
                                      where proTall.IdDetallePedido == idDetallePedido
                                      select proTall).ToList();

                foreach (var taProgramacion in programacionTaller)
                {
                    taProgramacion.TA_Taller = taProgramacion.TA_Taller;
                    taProgramacion.TA_DetalleOrdenPedido = taProgramacion.TA_DetalleOrdenPedido;
                    taProgramacion.TA_DetalleOrdenPedido.TA_Producto = taProgramacion.TA_DetalleOrdenPedido.TA_Producto;
                }

                return programacionTaller;

            }
        }
        public static bool EliminarProgramacionTaller(int idDetallePedid, int idProgramacionTaller)
        {
            using (var data = new TallerArtesanalDataContext())
            {

                TA_ProgramacionTaller programacionTaller = data.TA_ProgramacionTallers.FirstOrDefault(pt => pt.IdProgramacionTaller == idProgramacionTaller);

                if (programacionTaller != null) data.TA_ProgramacionTallers.DeleteOnSubmit(programacionTaller);

                data.SubmitChanges();

                return true;

            }
        }
        

        public static List<TA_ProgramacionTaller> ListadoProgramacionTallerByIdOrdenPedido(int idOrdenPedido)
        {
            List<TA_ProgramacionTaller> programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {

                programacionTaller = (from proTall in data.TA_ProgramacionTallers
                                      join detOp in data.TA_DetalleOrdenPedido on proTall.IdDetallePedido equals detOp.IdDetallePedido
                                      where detOp.IdOrdenPedido == idOrdenPedido
                                      select proTall).ToList();

                foreach (var taProgramacion in programacionTaller)
                {
                    taProgramacion.TA_Taller = taProgramacion.TA_Taller;
                    taProgramacion.TA_DetalleOrdenPedido = taProgramacion.TA_DetalleOrdenPedido;
                    taProgramacion.TA_DetalleOrdenPedido.TA_Producto = taProgramacion.TA_DetalleOrdenPedido.TA_Producto;
                }

                return programacionTaller;

            }
        }

        public static List<TA_Entrega> ListadoEntregas(int idProgramacionTaller, int idTaller)
        {
            List<TA_Entrega> entregas;

            using (var data = new TallerArtesanalDataContext())
            {
                entregas = (from ent in data.TA_Entregas
                            where ent.IdProgramacionTaller.Equals(idProgramacionTaller) && ent.IdTaller.Equals(idTaller)
                            select ent).ToList();

                foreach (var taEntrega in entregas)
                {
                    taEntrega.TA_ProgramacionTaller.TA_DetalleOrdenPedido.TA_Producto = taEntrega.TA_ProgramacionTaller.TA_DetalleOrdenPedido.TA_Producto;
                    taEntrega.TA_ProgramacionTaller.TA_DetalleOrdenPedido.TA_OrdenPedido = taEntrega.TA_ProgramacionTaller.TA_DetalleOrdenPedido.TA_OrdenPedido;
                    taEntrega.TA_Taller = taEntrega.TA_Taller;
                    taEntrega.porcentajeVariacion = (1 - ((taEntrega.CantidadEjecutada ?? 0) / (decimal)(taEntrega.CantidadProgramada ?? 1))) * 100 * -1;
                }

                return entregas;
            }
        }

        public static List<TA_Visita> ListadoAgendaVisitas(DateTime? fechaEntrega)
        {
            List<TA_Visita> visitas = null;

            using (var data = new TallerArtesanalDataContext())
            {

                visitas = (from proTall in data.TA_ProgramacionTallers
                           join ent in data.TA_Entregas on proTall.IdProgramacionTaller equals ent.IdProgramacionTaller
                           join tal in data.TA_Taller on ent.IdTaller equals tal.IdTaller
                           join detOrd in data.TA_DetalleOrdenPedido on proTall.IdDetallePedido equals detOrd.IdDetallePedido
                           join prod in data.TA_Producto on detOrd.IdProducto equals prod.IdProducto
                           join amb in data.TA_Ambito on tal.IdAmbito equals amb.IdAmbito
                           where ent.FechaEntrega == fechaEntrega
                           select new TA_Visita()
                           {
                               IdTaller = ent.IdTaller,
                               RazonSocialTaller = tal.RazónSocial,
                               IdProducto = prod.IdProducto,
                               DescripcionProducto = prod.Descripción,
                               CantidadAsignada = ent.CantidadProgramada,
                               Ambito = amb.Ambito1,
                               Localidad = amb.Localidad
                           }).ToList();

                return visitas;
            }
        }

        /// <summary>
        /// Se obtiene una Programacion
        /// </summary>
        /// <param name="numProgramacion">Id de Programacion</param>
        /// <returns>una Programacion</returns>
        public static TA_ProgramacionTaller ObtenerProgramacionTaller(int? numProgramacionTaller)
        {

            TA_ProgramacionTaller programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {
                programacionTaller = data.TA_ProgramacionTallers.FirstOrDefault(pro => pro.IdProgramacionTaller == numProgramacionTaller);
                return programacionTaller;
            }
        }

        public static TA_ProgramacionTaller ObtenerProgramacionTaller(int numProgramacion, int idTaller)
        {
            TA_ProgramacionTaller programacionTaller;

            using (var data = new TallerArtesanalDataContext())
            {
                programacionTaller = data.TA_ProgramacionTallers.FirstOrDefault(pro => pro.IdProgramacionTaller == numProgramacion && pro.IdTaller == idTaller);
                return programacionTaller;
            }
        }

        public static TA_ProgramacionTaller ActualizarProgramacionTaller(TA_ProgramacionTaller programacionTaller)
        {

            var _temp = new TA_ProgramacionTaller();
            TA_Entrega _tempEntrega;


            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_ProgramacionTallers.Where(pro => pro.IdProgramacionTaller.Equals(programacionTaller.IdProgramacionTaller) && pro.IdTaller.Equals(programacionTaller.IdTaller)).ToList().DefaultIfEmpty(_temp).FirstOrDefault();
                _temp.CantidadEntregas = programacionTaller.CantidadEntregas;

                foreach (var entrega in _temp.TA_Entregas)
                {
                    data.TA_Entregas.DeleteOnSubmit(entrega);
                }

                DateTime fechaCreacion = _temp.TA_DetalleOrdenPedido.TA_OrdenPedido.FechaCreación ?? DateTime.Now;
                DateTime fechaEntrega = _temp.TA_DetalleOrdenPedido.TA_OrdenPedido.FechaEntrega ?? DateTime.Now;

                TimeSpan dias = fechaEntrega - fechaCreacion;

                double cantidadDiasTotalEntrega = dias.TotalDays + 1;
                double cantidadDiasDeEntrega = (double)(cantidadDiasTotalEntrega / _temp.CantidadEntregas);

                fechaCreacion = fechaCreacion.AddDays(-1);

                for (int i = 0; i < _temp.CantidadEntregas; i++)
                {
                    fechaCreacion = fechaCreacion.AddDays(cantidadDiasDeEntrega);

                    _tempEntrega = new TA_Entrega();
                    _tempEntrega.IdProgramacionTaller = _temp.IdProgramacionTaller;
                    _tempEntrega.IdTaller = (int)_temp.IdTaller;
                    _tempEntrega.Entrega1 = "Entrega " + ((i < 9) ? "0" : "") + (i + 1);
                    _tempEntrega.FechaEntrega = fechaCreacion;
                    //_tempEntrega.Entrega = "td:" + cantidadDiasTotalEntrega + " /  cDE:" +cantidadDiasDeEntrega + " sfec:" + fechaCreacion;
                    _tempEntrega.CantidadProgramada = (_temp.CantidadAsignadas / _temp.CantidadEntregas);

                    data.TA_Entregas.InsertOnSubmit(_tempEntrega);

                }

                data.SubmitChanges();
            }

            return _temp;
        }

        /// <summary>
        /// Se grabar la asignación del taller
        /// </summary>
        /// <param name="idTaller">ID del Taller</param>
        /// <param name="idDetalleOP">ID del Detalle de la Orden de Pedido</param>
        /// <param name="cantAsignadas">Cantidad Asignadas para el taller</param>
        /// <returns>Valor del tipo booleano que indica el estado de la grabación</returns>
        public static TA_ProgramacionTaller GrabarProgramacion(TA_ProgramacionTaller progTaller)
        {

            var _temp = new TA_ProgramacionTaller();

            bool exito = true;
            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_ProgramacionTallers.Where(pro => pro.IdProgramacionTaller.Equals(progTaller.IdProgramacionTaller)).ToList().DefaultIfEmpty(_temp).FirstOrDefault();

                try
                {
                    if (_temp.IdProgramacionTaller == 0)
                    {
                        _temp.IdDetallePedido = progTaller.IdDetallePedido;
                        data.TA_ProgramacionTallers.InsertOnSubmit(_temp);
                        data.SubmitChanges();
                    }
                }
                catch
                {
                    exito = false;
                }
            }
            return _temp;
        }

        public static TA_Entrega GrabarRegistrarAvanceProduccion(int idEntrega, int cantidadEjecutada)
        {

            var _temp = new TA_Entrega();

            bool exito = true;
            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_Entregas.FirstOrDefault(e => e.IdEntrega.Equals(idEntrega));

                try
                {
                    _temp.CantidadEjecutada = cantidadEjecutada;
                    data.SubmitChanges();
                }
                catch
                {
                    exito = false;
                }
            }
            return _temp;
        }

        public static TA_ProgramacionTaller GrabarProgramacionTaller(TA_ProgramacionTaller progTall)
        {

            var _temp = new TA_ProgramacionTaller();

            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_ProgramacionTallers.Where(pro => pro.IdDetallePedido.Equals(progTall.IdDetallePedido) && pro.IdTaller.Equals(progTall.IdTaller)).ToList().DefaultIfEmpty(_temp).FirstOrDefault();

                _temp.CantidadAsignadas = progTall.CantidadAsignadas;

                try
                {
                    if (_temp.IdProgramacionTaller == 0)
                    {
                        _temp.IdDetallePedido = progTall.IdDetallePedido;
                        _temp.IdProgramacionTaller = progTall.IdProgramacionTaller;
                        _temp.IdTaller = progTall.IdTaller;

                        data.TA_ProgramacionTallers.InsertOnSubmit(_temp);
                    }
                    data.SubmitChanges();

                }
                catch
                {
                }
                return _temp;
            }
        }

        public static List<TA_SolicitudCotizacion> ListadoCotizacion(string estadoSolictud)
        {
            List<TA_SolicitudCotizacion> solicitudCotizaciones;

            using (var data = new TallerArtesanalDataContext())
            {
                solicitudCotizaciones = (from ent in data.TA_SolicitudCotizacion
                                         where ent.Estado.Equals(estadoSolictud)
                                         select ent).ToList();

                foreach (var cot in solicitudCotizaciones)
                {
                    cot.TA_Comprador = cot.TA_Comprador;
                }

                return solicitudCotizaciones;
            }
        }

        public static List<TA_DetalleSolicitud> ListadoDetalleCotizacionProductos(int idSolicitud)
        {
            List<TA_DetalleSolicitud> detalleCotizaciones;

            using (var data = new TallerArtesanalDataContext())
            {
                detalleCotizaciones = (from ent in data.TA_DetalleSolicitud
                                       where ent.IdSolicitud.Equals(idSolicitud)
                                       select ent).ToList();

                foreach (var cot in detalleCotizaciones)
                {
                    cot.TA_Producto = cot.TA_Producto;
                    cot.TA_Producto.TA_LineaProductiva = cot.TA_Producto.TA_LineaProductiva;
                }

                return detalleCotizaciones;
            }
        }

        public static TA_SolicitudCotizacion AprobarSolicitudCotizacion(int idSolicitud, DateTime fechaEntrega)
        {

            var _temp = new TA_SolicitudCotizacion();

            bool exito = true;
            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_SolicitudCotizacion.Where(pro => pro.IdSolicitud.Equals(idSolicitud)).ToList().DefaultIfEmpty(_temp).FirstOrDefault();

                try
                {
                    _temp.Estado = "Aprobado";
                    _temp.FechaEntrega = fechaEntrega;
                    data.SubmitChanges();
                }
                catch
                {
                    exito = false;
                }
            }
            return _temp;

        }

        public static TA_SolicitudCotizacion RechazarSolicitudCotizacion(int idSolicitud)
        {

            var _temp = new TA_SolicitudCotizacion();

            bool exito = true;
            using (var data = new TallerArtesanalDataContext())
            {
                _temp = data.TA_SolicitudCotizacion.Where(pro => pro.IdSolicitud.Equals(idSolicitud)).ToList().DefaultIfEmpty(_temp).FirstOrDefault();

                try
                {
                    _temp.Estado = "Rechazado";
                    data.SubmitChanges();
                }
                catch
                {
                    exito = false;
                }
            }
            return _temp;
        }
    }
}
